/*
	给定两个整数，被除数dividend和除数divisor。将两数相除，要求不使用乘法、除法和 mod 运算符。
	返回被除数dividend除以除数divisor得到的商。
	整数除法的结果应当截去（truncate）其小数部分，例如：truncate(8.345) = 8 以及 truncate(-2.7335) = -2
	示例1:
	输入: dividend = 10, divisor = 3
	输出: 3
	解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
	示例2:
	输入: dividend = 7, divisor = -3
	输出: -2
	解释: 7/-3 = truncate(-2.33333..) = -2
	提示：
	被除数和除数均为 32 位有符号整数。
	除数不为0。
	假设我们的环境只能存储 32 位有符号整数，其数值范围是 [−231, 231− 1]。本题中，如果除法结果溢出，则返回 231− 1。
*/
// 通过移位和减法实现，除法的算分；
// 思路：
//	找到 2^n * div < dividend 最近的值
//  结果表明的 2 ^n 是结果
//  然后，dividend = dividend - 2^n * div
//  重复上面内容

package main

import (
	"fmt"
	"math"
)

//需要用到int32类型的最大值和最小值，但是查了查在go的标准库中没有定义这些变量，所以当需要使用整数类型的最大值和最小值的时候，我们需要自己手动去定义。

// 自我定义的常量值
const INT_MAX = int32(^uint32((0)) >> 1) // 在计算机中存储的反码，0的取反，然后，右移 得到最大值；第一位 0代表负数，后面全取 1 为最大值；
const INT_MIN = ^INT_MAX                 // 获取反码的 最大值

func divide(dividend int, divisor int) int {
	// 处理溢出情形；
	fmt.Printf("MIN:%d",INT_MIN )
	fmt.Printf("MIN:%d",INT_MAX )

	if divisor == -1 && dividend == int(INT_MIN){
		return int(INT_MAX)
	}
	neg:=1
	if dividend <0  {
		neg*=-1
	}
	if divisor<0{
		neg*=-1
	}
	div := int(math.Abs(float64(dividend)))
	diver := int(math.Abs(float64(divisor)))
	res := 0

	for i := 31; i >=0; i-- {
		if div>>i >= diver { // div >> i ，div 除以 2的i 次方;
			res += 1 << i // 结果等于 2 的n 次方
			div -= diver << i
		}
	}
	return int(res*neg)
}

func main() {
	fmt.Printf("%d", divide(7, -3))
}
